From 1ea38575248fdf0467a8a57a9a43301e33592024 Mon Sep 17 00:00:00 2001
From: Pedro Gimeno <pgimeno@users.noreply.notabug.org>
Date: Tue, 25 Jun 2019 13:36:22 +0200
Subject: [PATCH] Add FFI pointer and size retrieval and sanity check functions

---
 src/mapnode.cpp                 |  9 +++++++++
 src/porting.h                   |  2 ++
 src/script/lua_api/l_noise.cpp  | 44 +++++++++++++++++++++++++++++++++++++++++
 src/script/lua_api/l_noise.h    |  2 ++
 src/script/lua_api/l_vmanip.cpp | 20 +++++++++++++++++++
 5 files changed, 77 insertions(+)

diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 9761a661..b6840eb1 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 #include <string>
 #include <sstream>
+#include <cstddef>
 
 static const Rotation wallmounted_to_rot[] = {
 	ROTATE_0, ROTATE_180, ROTATE_90, ROTATE_270
@@ -44,6 +45,14 @@ static const u8 rot_to_wallmounted[] = {
 	MapNode
 */
 
+extern "C" EXPORT int get_mapnode_version(void)
+{
+	if (sizeof(MapNode) == 4 && offsetof(MapNode, param0) == 0
+			&& offsetof(MapNode, param1) == 2 && offsetof(MapNode, param2) == 3)
+		return 1;
+	return 0;
+}
+
 void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const
 {
 	if (f.palette) {
diff --git a/src/porting.h b/src/porting.h
index 4d30a597..56419ff9 100644
--- a/src/porting.h
+++ b/src/porting.h
@@ -54,6 +54,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 	#include <windows.h>
 
 	#define sleep_ms(x) Sleep(x)
+	#define EXPORT __declspec(dllexport)
 #else
 	#include <unistd.h>
 	#include <cstdint> //for uintptr_t
@@ -67,6 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 	#endif
 
 	#define sleep_ms(x) usleep(x*1000)
+	#define EXPORT
 #endif
 
 #ifdef _MSC_VER
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp
index e38d319f..47955977 100644
--- a/src/script/lua_api/l_noise.cpp
+++ b/src/script/lua_api/l_noise.cpp
@@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include "config.h"
 #include "lua_api/l_noise.h"
 #include "lua_api/l_internal.h"
 #include "common/c_converter.h"
@@ -401,6 +402,49 @@ luaL_Reg LuaPerlinNoiseMap::methods[] = {
 	{0,0}
 };
 
+extern "C" {
+
+EXPORT size_t PerlinNoiseMap_get_area(void **pnmp)
+{
+	NO_MAP_LOCK_REQUIRED;
+
+	if (pnmp == nullptr)
+		throw ModError("Nil pointer in C call");
+
+	LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)pnmp;
+
+	Noise *n = o->getNoise();
+
+	return n->sx * n->sy;
+}
+
+EXPORT size_t PerlinNoiseMap_get_volume(void **pnmp)
+{
+	NO_MAP_LOCK_REQUIRED;
+
+	if (pnmp == nullptr)
+		throw ModError("Nil pointer in C call");
+
+	LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)pnmp;
+
+	Noise *n = o->getNoise();
+
+	return n->sx * n->sy * n->sz;
+}
+
+EXPORT void PerlinNoiseMap_get_pointer(void **pnmp, void **ptr)
+{
+	NO_MAP_LOCK_REQUIRED;
+
+	if (pnmp == nullptr || ptr == nullptr)
+		throw ModError("Nil pointer in C call");
+
+	LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)pnmp;
+	*ptr = o->getNoise();
+}
+
+} // extern "C"
+
 ///////////////////////////////////////
 /*
 	LuaPseudoRandom
diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h
index 9f50dfd3..49a7ec6e 100644
--- a/src/script/lua_api/l_noise.h
+++ b/src/script/lua_api/l_noise.h
@@ -91,6 +91,8 @@ class LuaPerlinNoiseMap : public ModApiBase
 	static LuaPerlinNoiseMap *checkobject(lua_State *L, int narg);
 
 	static void Register(lua_State *L);
+
+	Noise *getNoise() const { return noise; }
 };
 
 /*
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index c92983bd..8401657d 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -30,6 +30,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapgen/mapgen.h"
 #include "voxelalgorithms.h"
 
+extern "C" {
+
+EXPORT void VoxelManip_get_pointer(void **lvmp, void **ptr)
+{
+	if (lvmp == nullptr || ptr == nullptr)
+		throw ModError("Nil pointer in C call");
+
+	*ptr = (*(LuaVoxelManip **)lvmp)->vm->m_data;
+}
+
+EXPORT s32 VoxelManip_get_volume(void **lvmp)
+{
+	if (lvmp == nullptr)
+		throw ModError("Nil pointer in C call");
+
+	return (*(LuaVoxelManip **)lvmp)->vm->m_area.getVolume();
+}
+
+} // extern "C"
+
 // garbage collector
 int LuaVoxelManip::gc_object(lua_State *L)
 {
-- 
2.11.0

